//
//  ViewController.swift
//  FlightInfo
//
//  Created by 涂晶 on 16/6/8.
//  Copyright © 2016年 TuJing. All rights reserved.
//

import UIKit
import QuartzCore

//
// Util delay function
//
func delay(seconds seconds: Double, completion:()->()) {
    let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64( Double(NSEC_PER_SEC) * seconds ))
    
    dispatch_after(popTime, dispatch_get_main_queue()) {
        completion()
    }
}

class ViewController: UIViewController {
    
    @IBOutlet var bgImageView: UIImageView!
    
    @IBOutlet var summaryIcon: UIImageView!
    @IBOutlet var summary: UILabel!
    
    @IBOutlet var flightNr: UILabel!
    @IBOutlet var gateNr: UILabel!
    @IBOutlet var departingFrom: UILabel!
    @IBOutlet var arrivingTo: UILabel!
    @IBOutlet var planeImage: UIImageView!
    
    @IBOutlet var flightStatus: UILabel!
    @IBOutlet var statusBanner: UIImageView!
    
    var snowView: SnowView!
    
    enum AnimationDirection: Int {
        case Positive = 1
        case Negative = -1
    }
    
    //MARK: view controller methods
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        summary.addSubview(summaryIcon)
        summaryIcon.center.y = summary.frame.size.height/2
        
        snowView = SnowView(frame: CGRect(x: -150, y:-100, width: 300, height: 50))
        let snowClipView = UIView(frame: CGRectOffset(view.frame, 0, 50))
        snowClipView.clipsToBounds = true
        snowClipView.addSubview(snowView)
        view.addSubview(snowClipView)
        
        changeFlightDataTo(londonToParis)
    }
    
    //MARK: custom methods
    
    func changeFlightDataTo(data: FlightData, animated: Bool = false) {
        
        if animated {
            planeDepart()
            summarySwitchTo(data.summary)
            
            fadeImageView(bgImageView, toimage: UIImage(named: data.weatherImageName)!, showEffects: data.showWeatherEffects)
            let direction: AnimationDirection = data.isTakingOff ? .Positive : .Negative
            
            cubeTransition(label: flightNr, text: data.flightNr, direction: direction)
            cubeTransition(label: gateNr, text: data.gateNr, direction: direction)
            
            let offsetDeparting = CGPoint(x: CGFloat(direction.rawValue*80), y: 0.0)
            moveLabel(departingFrom, text: data.departingFrom, offset: offsetDeparting)
            
            let offsetArriving = CGPoint(x: 0.0, y: CGFloat(direction.rawValue*50))
            moveLabel(arrivingTo, text: data.arrivingTo, offset: offsetArriving)
            
            
        }else {
            bgImageView.image = UIImage(named: data.weatherImageName)
            snowView.hidden = !data.showWeatherEffects
            
            flightNr.text = data.flightNr
            gateNr.text = data.gateNr
            
            departingFrom.text = data.departingFrom
            arrivingTo.text = data.arrivingTo
            
            flightStatus.text = data.flightStatus
            summary.text = data.summary
        }
        
        delay(seconds: 3.0) {
            self.changeFlightDataTo(data.isTakingOff ? parisToRome : londonToParis, animated: true)
        }
    }
    
    // change image
    
    func fadeImageView(imageView: UIImageView, toimage: UIImage, showEffects: Bool) {
        UIView.transitionWithView(imageView, duration: 1.0, options: [.TransitionCrossDissolve], animations: {
            imageView.image = toimage
            }, completion: nil)
        
        UIView.animateWithDuration(1.0, delay: 0.0, options: [.CurveEaseOut], animations: {
            self.snowView.alpha = showEffects ? 1.0 : 0.0
            }, completion: nil)
    }
    
    func cubeTransition(label label: UILabel, text: String, direction: AnimationDirection) {
        let auxLabel = UILabel(frame: label.frame)
        auxLabel.text = text
        auxLabel.font = label.font
        auxLabel.textAlignment = label.textAlignment
        auxLabel.textColor = label.textColor
        auxLabel.backgroundColor = label.backgroundColor
        
        let auxLabelPffset = CGFloat(direction.rawValue) * label.frame.size.height/2.0
        auxLabel.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(1.0, 0.1), CGAffineTransformMakeTranslation(0.0, auxLabelPffset))
        
        label.superview!.addSubview(auxLabel)
        
        UIView.animateWithDuration(0.5, delay: 0.0, options: [.CurveEaseOut], animations: {
            auxLabel.transform = CGAffineTransformIdentity
            label.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(1.0, 0.1), CGAffineTransformMakeTranslation(0.0, -auxLabelPffset))
            }, completion: {_ in
                label.text = auxLabel.text
                label.transform = CGAffineTransformIdentity
                auxLabel.removeFromSuperview()
        })
        
    }
    
    func moveLabel(label: UILabel, text: String, offset: CGPoint) {
        let auxLabel = UILabel(frame: label.frame)
        auxLabel.text = text
        auxLabel.font = label.font
        auxLabel.textAlignment = label.textAlignment
        auxLabel.textColor = label.textColor
        auxLabel.backgroundColor = UIColor.clearColor()
        
        auxLabel.transform = CGAffineTransformMakeTranslation(offset.x, offset.y)
        auxLabel.alpha = 0.0
        view.addSubview(auxLabel)
        
        UIView.animateWithDuration(0.5, delay: 0.0, options: .CurveEaseIn, animations: {
            label.transform = CGAffineTransformMakeTranslation(offset.x, offset.y)
            label.alpha = 0.0
            }, completion: nil)
        
        UIView.animateWithDuration(0.25, delay: 0.1, options: .CurveEaseIn, animations: {
            auxLabel.transform = CGAffineTransformIdentity
            auxLabel.alpha = 1.0
            }, completion: {_ in
                auxLabel.removeFromSuperview()
                
                label.text = text
                label.alpha = 1.0
                label.transform = CGAffineTransformIdentity
            }
        )
        
    }
    
    func planeDepart() {
        let originalCenter = planeImage.center
        
        UIView.animateKeyframesWithDuration(1.5, delay: 0.0, options: [], animations: {
            UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.25, animations: {
                self.planeImage.center.x += 80.0
                self.planeImage.center.y -= 10.0
            })
            
            UIView.addKeyframeWithRelativeStartTime(0.1, relativeDuration: 0.4, animations: {
                self.planeImage.transform = CGAffineTransformMakeRotation(CGFloat(-M_PI_4/2))
            })
            
            UIView.addKeyframeWithRelativeStartTime(0.25, relativeDuration: 0.25, animations: {
                self.planeImage.center.x += 100.0
                self.planeImage.center.y -= 50.0
                self.planeImage.alpha = 0.0
            })
            
            UIView.addKeyframeWithRelativeStartTime(0.51, relativeDuration: 0.01, animations: {
                self.planeImage.transform = CGAffineTransformIdentity
                self.planeImage.center = CGPoint(x: 0.0, y: originalCenter.y)
            })
            
            UIView.addKeyframeWithRelativeStartTime(0.55, relativeDuration: 0.45, animations: {
                self.planeImage.alpha = 1.0
                self.planeImage.center = originalCenter
            })
            }, completion: nil)
    }
    
    func summarySwitchTo(summaryText: String) {
        UIView.animateKeyframesWithDuration(1.0, delay: 0.0, options: [], animations: {
            UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.45, animations: {
                self.summary.center.y -= 100.0
            })
            UIView.addKeyframeWithRelativeStartTime(0.45, relativeDuration: 0.01, animations: {
                
            })
            UIView.addKeyframeWithRelativeStartTime(0.5, relativeDuration: 0.45, animations: {
                self.summary.center.y += 100.0
            })
            }, completion: nil)
        
        delay(seconds: 0.5, completion: {
            self.summary.text = summaryText
        })
    }
}